<!-- 照片墙组件 -->
<template>
    <el-upload
        ref="upload"
        :http-request="httpRequest"
        :multiple="true"
        :accept="accept"
        :action="action"
        list-type="picture-card"
        :limit="imglen"
        :file-list="imgeData"
        :before-upload="beforeUpload"
        :on-preview="onClickPreview"
        :on-remove="onClickDelete"
        :on-error="onError"
    >
        <i class="el-icon-plus"></i>
        <slot name="tip" slot="tip"></slot>
    </el-upload>
    <el-dialog v-model="dialogVisible">
        <div class="dialog-img">
            <img class="img" width="100%" :src="showImg" alt="" />
        </div>
    </el-dialog>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, getCurrentInstance, watch, toRefs } from 'vue';
export default defineComponent({
    props: {
        file: {
            type: String,
            default: ''
        },
        accept: {
            type: String,
            default: 'image/gif, image/jpeg, image/png'
        },
        folder: {
            type: String,
            default: 'default'
        },
        tip: {
            type: String,
            default: ''
        },
        imglen: {
            type: Number,
            default: 1
        },
        limit: {
            type: Number,
            default: 1
        },
        width: {
            type: Number,
            default: 1
        },
        height: {
            type: Number,
            default: 1
        }
    },
    emits: ['on-error', 'input'],
    setup(prop, ctx) {
        watch(
            () => prop.file,
            (val) => {
                console.log(val);
            }
        );
        const instance: any = getCurrentInstance();
        const GL = instance.appContext.config.globalProperties;
        const state = reactive({
            dialogVisible: false,
            loading: false,
            showImg: ''
        });
        const upload: any = ref({});
        const imgeData: any = ref([]);
        const imgeIdData: any = ref([]);
        const action: string = GL.$api.uploadImg || '';

        const httpRequest = () => {
            state.loading = true;
            const formData = new FormData();
            formData.append('file', upload.value.file);
            formData.append('folder', prop.folder);
            formData.append('domain', '1');
            GL.$axios
                .post(GL.$api.uploadImg, formData)
                .then((res: any) => {
                    onSuccess(res);
                })
                .catch((err: any) => {
                    onError(err);
                });
        };
        const onClickPreview = (e) => {
            state.showImg = e.url;
            state.dialogVisible = true;
        };
        const beforeUpload = (file: any) => {
            const isFormat = file.type.includes('image');
            const isLtxM = file.size / 1024 / 1024 < prop.limit;
            if (!isFormat) {
                GL.$message.error('上传格式错误!');
                return false;
            }
            if (!isLtxM) {
                GL.$message.error(`上传图片大小不能超过${prop.limit}MB!`);
                return false;
            }
            const isSize = new Promise((resolve, reject) => {
                if (prop.height && prop.width) {
                    const width = prop.width; // 限制图片尺寸为654X270
                    const height = prop.height;
                    const url: any = window.URL;
                    const img = new Image();
                    img.onload = () => {
                        const valid = (img.width / img.height).toFixed(2) === (width / height).toFixed(2);
                        valid ? resolve('') : reject(new Error('尺寸不合法'));
                    };
                    img.src = url.createObjectURL(file);
                } else {
                    resolve('');
                }
            }).then(
                () => {
                    return file;
                },
                () => {
                    GL.$message.error(`图片尺寸限制比例为${prop.width} * ${prop.height}`);
                    return Promise.reject(new Error('尺寸不合法'));
                }
            );
            if (!isSize) {
                return false;
            }

            return isFormat && isLtxM && isSize;
        };

        const onClickDelete = (file: any) => {
            imgeData.value.forEach((element: any, index: number) => {
                if (element.uid === file.uid) {
                    imgeData.value.splice(index, 1);
                }
            });
            returnimgs();
        };

        const returnimgs = () => {
            imgeIdData.value = [];
            for (let i = 0; i < imgeData.value.length; i++) {
                imgeIdData.value.push(imgeData.value[i].url);
            }
            // 数据处理
            ctx.emit('input', imgeIdData.value.join(','));
        };
        const onSuccess = (response: any) => {
            state.loading = false;
            imgeData.value.push({ url: response.data.path });
            returnimgs();
        };
        const onError = (err: any) => {
            state.loading = false;
            ctx.emit('on-error', err);
            GL.$message.error('上传失败请重新上传！');
        };
        return {
            ...toRefs(state),
            imgeData,
            upload,
            action,
            onClickPreview,
            httpRequest,
            beforeUpload,
            onClickDelete,
            onError
        };
    }
});
</script>
<style lang="scss" scoped>
:deep(.el-upload-list__item.is-ready ){
  display: none;
}
</style>
